package com.zpb.framework.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.zpb.framework.domain.ApiResult;

import com.zpb.framework.domain.dto.RoleAddDto;
import com.zpb.framework.domain.dto.RoleChangeStatusDto;
import com.zpb.framework.domain.dto.RoleQueryDto;
import com.zpb.framework.domain.dto.RoleUpdateDto;
import com.zpb.framework.domain.entity.Role;
import com.zpb.framework.domain.entity.RoleMenu;
import com.zpb.framework.domain.enums.ResultCodeEnum;
import com.zpb.framework.domain.vo.PageVo;
import com.zpb.framework.domain.vo.RoleVo;
import com.zpb.framework.mapper.MenuMapper;
import com.zpb.framework.mapper.RoleMapper;
import com.zpb.framework.mapper.RoleMenuMapper;
import com.zpb.framework.service.RoleService;
import com.zpb.framework.utils.BeanCopyUtil;
import com.zpb.framework.utils.DictCodeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @Description:
 * @Author: zhaopengbo
 * @Date: 2025/9/22
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {

    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private MenuMapper menuMapper;
    @Autowired
    private RoleMenuMapper roleMenuMapper;


    @Override
    public ApiResult<PageVo> getRoleList(Integer pageNum, Integer pageSize, RoleQueryDto query) {
        Page<Role> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(query.getRoleName() != null && !query.getRoleName().equals(""), Role::getRoleName, query.getRoleName())
                .eq(query.getRoleName() != null, Role::getStatus, query.getStatus())
                .orderByAsc(Role::getRoleSort);
        page(page, queryWrapper);
        List<Role> roles = page.getRecords();

        List<RoleVo> roleVos = BeanCopyUtil.copyBeanList(roles, RoleVo.class);

        PageVo pageVo = new PageVo(page.getTotal(),roleVos);
        return ApiResult.success(pageVo);
    }

    @Override
    public ApiResult changeStatus(RoleChangeStatusDto roleChangeStatusDto) {
        Role role = BeanCopyUtil.copyBean(roleChangeStatusDto, Role.class);
        int result = roleMapper.updateById(role);
        if (result>0){
            return ApiResult.success();
        }
        return ApiResult.failure(ResultCodeEnum.UPDATE_FAILURE);
    }

    @Override
    @Transactional
    public ApiResult addRole(RoleAddDto roleAddDto) {
        Role role = BeanCopyUtil.copyBean(roleAddDto, Role.class);
        int result = roleMapper.insert(role);
        if (result==0){
            return ApiResult.failure(ResultCodeEnum.ADD_FAILURE);
        }
        List<Long> menuIds = roleAddDto.getMenuIds();
        if (menuIds!=null && menuIds.size()>0){
            int iResult = roleMapper.insertRoleMenuByMenuId(role.getId(), roleAddDto.getMenuIds());
            if (iResult==0){
                return ApiResult.failure(ResultCodeEnum.ADD_FAILURE);
            }
        }
        return ApiResult.success();
    }

    @Override
    public ApiResult<RoleVo> getRoleById(Long id) {
        Role role = roleMapper.selectById(id);
        if (role==null){
            return ApiResult.failure(ResultCodeEnum.NO_ROLE);
        }
        RoleVo roleVo = BeanCopyUtil.copyBean(role, RoleVo.class);
        return ApiResult.success(roleVo);
    }

    @Override
    @Transactional
    public ApiResult updateRole(RoleUpdateDto roleUpdateDto) {
        Role role = BeanCopyUtil.copyBean(roleUpdateDto, Role.class);
        int result = roleMapper.updateById(role);
        if (result==0){
            return ApiResult.failure(ResultCodeEnum.UPDATE_FAILURE);
        }
        LambdaQueryWrapper<RoleMenu> roleMenuLambdaQueryWrapper = new LambdaQueryWrapper<>();
        roleMenuLambdaQueryWrapper.eq(RoleMenu::getRoleId, role.getId());
        roleMenuMapper.delete(roleMenuLambdaQueryWrapper);

        List<Long> menuIds = roleUpdateDto.getMenuIds();
        Long roleId = role.getId();
        menuIds.forEach(mid->{
            roleMenuMapper.insert(new RoleMenu(roleId, mid));
        });
        return ApiResult.success();
    }

    @Override
    public ApiResult<List<RoleVo>> getAllRoleList() {
        LambdaQueryWrapper<Role> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Role::getStatus, DictCodeUtil.NORMAL_STATUS);
        List<Role> roles = roleMapper.selectList(wrapper);
        List<RoleVo> roleVos = BeanCopyUtil.copyBeanList(roles, RoleVo.class);
        return ApiResult.success(roleVos);
    }
}